{***************************************************************
    SpyGestion  Copyright (C) 2008 Christophe KOALI <nature2gas@gmail.com>
    
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.
    
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
    
    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
    
****************************************************************}
unit modParsingClassIFlotte1;

interface

uses modParsingClassBase,
     modBaseType,
     Classes,
     sFonctionsChaines,
     SysUtils,
     Windows,

     modFlotteEnVoyage,          // collection de flotte en voyage
     modFlotteVaisseauxChoix,    // collection de vaisseaux disponible


     LibXmlParser;


type
    TFlotteSelectionInWhat = (fsiwNeant, fsiwListDesFlottes, fsiwVaisseauChoix);

    ////////////////////////////////////////////////////////////////////
    // Page flotte 1, sélection des vaisseaux à envoyer
    TParsingFlotte1_ChoixVaisseaux = class(IParsingRedirection)
    private
       //
       // Informations qui vont être extraites
       //

        FVaisseauxList: TCollectionVaisseauSelInfos;
        FFlotteList   : TCollectionFlotteListEnVoyage;


        // Flotte maximale possible
        FFlotteMax : integer;
        FFlotteUsed: integer;


        FFlotteAmiralDeFlotte: boolean;


        // Attention: Il existe d'autre formulaire pour le retour de flotte
        FURLToPostChoixVaisseaux: string;




       //
       // Variables qui vont aider à se repérer dans la page
       //




        FCurrTableLigne  : integer;
        FCurrTableColonne: integer;

        FFormulaireCountHidden: integer;
        FFormulaireRetourFound: boolean;
        FInForm: boolean;


        FInWhat: TFlotteSelectionInWhat;



       //
       // Variables qui vont aider à l'extraction des données
       //
        FLastABaliseTitle: string;

        FCurrentVaisseau: TVaisseauSelInfos;
        FCurrentFlotte  : TFlotteListEnVoyage;

        // Correspond au bouton pour soumettre la sélection des vaisseaux à envoyer
        // Si ce bouton n'existe pas, cela signifie que tous les slots de flotte sont
        // occupés
        FBoutonSubmitExist: boolean;



        procedure InitVaisseau;
        procedure InitFlotte;

        function IsValidVaisseau: boolean;
        function IsValidFlotte: boolean;


        procedure TraiteContentVaisseauxList(Content: string);
        procedure TraiteContentFlotteList(Content: string);

        procedure AddHidden(KeyName, Value: string);
        function GetKeyNameGID(KeyName: string; var KeySansLeGID: string): integer;

    public
       //
       // Informations ont été extraites
       //

       property URLToPost : string  read FURLToPostChoixVaisseaux write FURLToPostChoixVaisseaux;
       property FlotteMax : integer read FFlotteMax;
       property FlotteUsed: integer read FFlotteUsed;

       property VaisseauxList: TCollectionVaisseauSelInfos   read FVaisseauxList;
       property FlotteList   : TCollectionFlotteListEnVoyage read FFlotteList;

       property AmiralDeFlottePresent: boolean read FFlotteAmiralDeFlotte;
       



       

       /////////////////////////////////////////////////////////////////////////
       // Implémentation de IParsingRedirection

        // initialise l'interface
        procedure Initialisation; override;

        // obtient le résultat d'analyse
        function  GetFinalState: TParsingResultState; override;

        procedure SetFullURLFromBase(const BaseLink: string); override;


        procedure ScanOnStartTag(Sender: TObject; TagName: string; Attributes: TAttrList); override;
        procedure ScanOnEndTag(Sender: TObject; TagName: string); override;
        procedure ScanOnContent(Sender: TObject; Content: string); override;

       //
       /////////////////////////////////////////////////////////////////////////



       constructor Create;
       destructor Destroy; override;

    end;


implementation

uses modLanguageParsing,
     sHTMLFonctions,
     modApercuMsg,
     ESBDates,
     modCore;



procedure TParsingFlotte1_ChoixVaisseaux.Initialisation;
begin
       //
       // Informations qui vont être extraites
       //


    FFlotteMax  := -1;
    FFlotteUsed := -1;


    FVaisseauxList.Clear;
    FFlotteList.Clear;


        FFlotteAmiralDeFlotte := false;
        FURLToPostChoixVaisseaux := '';




       //
       // Variables qui vont aider à se repérer dans la page
       //

        FCurrTableLigne   := -1;
        FCurrTableColonne := -1;

        FFormulaireCountHidden := 0;
        FFormulaireRetourFound := false;
        FInForm                := false;

    FInWhat := fsiwNeant;








       //
       // Variables qui vont aider à l'extraction des données
       //

    InitVaisseau;
    InitFlotte;

    FBoutonSubmitExist := false;





    FError := false;

end;

function TParsingFlotte1_ChoixVaisseaux.GetFinalState: TParsingResultState;
begin
    Result := PRESULT_ECHEC;

    FFlotteUsed := FFlotteList.Count;

    if FFlotteMax <= 0 then
       FError := true;


    if FBoutonSubmitExist = false then begin
       // Réinitialise l'url
       FURLToPostChoixVaisseaux := '';
    end;

    if FError then begin
       exit;
    end;


    Result := NoT(PRESULT_ECHEC);
end;



procedure TParsingFlotte1_ChoixVaisseaux.SetFullURLFromBase(const BaseLink: string);
begin
    inherited;
    
    if FURLToPostChoixVaisseaux <> '' then
       FURLToPostChoixVaisseaux  := sHTML_Get_URL_Lien(BaseLink, FURLToPostChoixVaisseaux);

    FFlotteList.SetURLOfPage(BaseLink);
end;

function TParsingFlotte1_ChoixVaisseaux.GetKeyNameGID(KeyName: string; var KeySansLeGID: string): integer;
var lng, xPos: integer;
begin

    // Tous les id des vaisseaux sont compris entre 200 et 299 (donc commence par un 2)
    // Ceci dit, on pourrait aussi identifié l'id de manière plus classique

    KeySansLeGID := '';
    lng := length(KeyName);

    if lng <= 4 then exit;

    // Le nombre tient sur 3 chiffres et est en fin de chaine
    KeySansLeGID := copy(KeyName, 1, lng - 3);
    System.Delete(KeyName, 1, lng - 3);

    Result := StrToIntDef(KeyName, -1);
    


end;

procedure TParsingFlotte1_ChoixVaisseaux.AddHidden(KeyName, Value: string);
var kGID: integer;
    KeySansLeGID: string;
begin

   kGID := GetKeyNameGID(KeyName, KeySansLeGID);

   if kGID <= 0 then exit;


   if FCurrentVaisseau.GID <= 0 then begin
      FCurrentVaisseau.GID := kGID;

   end else begin
      // Vérifie sinon si le gid correspond à celui actuel
      if FCurrentVaisseau.GID <> kGID then begin
         // Erreur fatale
         FError := true;
         exit;
      end;

   end;

(*   <tr height="20">
    <th><a title="Vitesse: 15000">Grand transporteur</a></th>
    <th>29<input type="hidden" name="maxship203" value="29"/></th>
<!--    <th>15000 -->
     <input type="hidden" name="consumption203" value="50"/>
     <input type="hidden" name="speed203" value="15000" /></th>
     <input type="hidden" name="capacity203" value="25000" /></th>
     <th><a href="javascript:maxShip('ship203');" >max</a> </th>
     <th><input name="ship203" size="10" value="0" alt="Grand transporteur 29"/></th>
   </tr>
*)


   if SameText(KeySansLeGID, 'maxship') then begin
      FCurrentVaisseau.Max := StrToIntDef(Value, -1);

   end else if SameText(KeySansLeGID, 'consumption') then begin
      FCurrentVaisseau.Consomation := StrToIntDef(Value, -1);

   end else if SameText(KeySansLeGID, 'speed') then begin
      FCurrentVaisseau.Speed := StrToIntDef(Value, -1);

   end else if SameText(KeySansLeGID, 'capacity') then begin
      FCurrentVaisseau.Capacite := StrToIntDef(Value, -1);

   end;

   if FCurrentVaisseau.AllHiddenInput = '' then
      FCurrentVaisseau.AllHiddenInput := KeyName + '=' + Value
   else
      FCurrentVaisseau.AllHiddenInput := FCurrentVaisseau.AllHiddenInput + '&' + KeyName + '=' + Value;

end;


procedure TParsingFlotte1_ChoixVaisseaux.ScanOnStartTag(Sender: TObject; TagName: string; Attributes: TAttrList);
var CurrBalise, CurrXX: string;
    sMisc: string;
    sGID: integer;
begin


    TagName := lowercase(TagName);

    if TagName = 'form' then begin
       // Pour le formulaire de choix des vaisseaux:
       //<form action="flotten2.php?session=0000" method="POST">

       // Pour le bouton de retour de flotte dans la liste des flottes:
       //<form action="flotten1.php?session=0000" method="POST">

       CurrBalise := Attributes.Value('action');
       FInForm := true;

       if pos('flotten2', CurrBalise) > 1 then begin
          // Update 77c, c'est la form qui détermine le changement de données
          // car ils ont ajouté un tableau supplémentaire...
          FInWhat := fsiwVaisseauChoix;
       end;

       if FInWhat = fsiwVaisseauChoix then begin
          FURLToPostChoixVaisseaux := CurrBalise;

       end else begin
          FFormulaireCountHidden := 0;

          if FFormulaireRetourFound then begin
             FInForm := false;
          end else begin
             FCurrentFlotte.ReturnDataURL := CurrBalise;
          end;
       end;



    end else if TagName = 'a' then begin
       FLastABaliseTitle := Attributes.Value('title');


    end else if TagName = 'table' then begin
       FCurrTableLigne   := 0;
       FCurrTableColonne := 0;

       // fsiwListDesFlottes



    end else if TagName = 'tr' then begin
       Inc(FCurrTableLigne);
       FCurrTableColonne := 0;


       if FInWhat = fsiwVaisseauChoix then begin
          if IsValidVaisseau then begin
             // Ajoute le vaisseau dans la liste
             FVaisseauxList.Add(FCurrentVaisseau);
          end;

          InitVaisseau;

       end else if FInWhat = fsiwListDesFlottes then begin

          if IsValidFlotte then begin
             FFlotteList.Add(FCurrentFlotte);
          end;

          InitFlotte;
       end;

    end else if (TagName = 'td') or (TagName = 'th') then begin
       Inc(FCurrTableColonne);


    end else if TagName = 'input' then begin
       // <input type="hidden" name="consumption203" value="50"/>


       CurrBalise := lowercase(Attributes.Value('type'));


       if FInWhat = fsiwVaisseauChoix then begin

          if SameText(CurrBalise, 'hidden') then begin

             AddHidden(Attributes.Value('name'), Attributes.Value('value'));


          end else if CurrBalise = '' then begin
             // simple input box, c'est à dire le champs où l'on saisie le nombre
             // de vaisseaux que l'on veut utiliser

             sGID := GetKeyNameGID(Attributes.Value('name'), sMisc);

             if FCurrentVaisseau.GID = sGID then begin
                // Ok, cela correspond

                if SameText(sMisc, 'ship') then begin
                   // Ok, bonne valeur
                   // Rempli le champ, il faut 0 par défaut
                   FCurrentVaisseau.InputNameForChoix := Attributes.Value('name') + '=';

                end;

             end;


          end else if SameText(CurrBalise, 'submit') then begin
              // Le bouton submit existe, sinon cela signifie que l'on a atteint le
              // nb de flotte maxi
              // Il ne peut pas être confondu avec un autre bouton submit de retour
              // de flotte car on est toujours dans le if FInWhat = fsiwVaisseauChoix
              FBoutonSubmitExist := true;

          end;


       end else if FInWhat = fsiwListDesFlottes then begin

          if FCurrentFlotte.Numero > 0 then begin

             if FInForm then begin


                if SameText(CurrBalise, 'hidden') then begin
                   // A présent, il se peut qu'il y ai deux FORM
                   // pour une flotte
                   // - Une FORM pour le groupement de flotte
                   // - Une FORM pour le retour de flotte
                   //
                   // Il faut identifier la bonne form...
                   //

                   Inc(FFormulaireCountHidden);

                   if FFormulaireRetourFound then begin

                      if FFormulaireCountHidden > 1 then begin
                         // Erreur, car il y a qu'un seul champ
                         // dans le formulaire retour
                         FCurrentFlotte.ReturnDataToPost := '';
                         FError := true;

                      end else begin
                         // FFormulaireCountHidden = 1
                         // C'est un autre formulaire qui vient de commencer
                         // celui du groupement
                         FFormulaireCountHidden := 0;
                      end;
                   end;

                   CurrXX := Attributes.Value('name');

                   if SameText('order_return', CurrXX) then begin
                      // formulaire de retour de flotte
                      FFormulaireRetourFound := true;

                      FCurrentFlotte.ReturnDataToPost := CurrXX + '=' + Attributes.Value('value');
                   end;


                end; // hidden

             end; // in form
          end; // numero de flotte
       end; // fsiwListDesFlottes



    end;


end;

procedure TParsingFlotte1_ChoixVaisseaux.ScanOnEndTag(Sender: TObject; TagName: string);
begin
    TagName := lowercase(TagName);

    if TagName = 'table' then begin

       if FInWhat = fsiwListDesFlottes then begin
          // La prochaine table correspondra au choix des flottes
          if IsValidFlotte then begin
             FFlotteList.Add(FCurrentFlotte);
          end;
          InitFlotte;

          // Update 77c, c'est la form qui détermine le changement de données
          // car ils ont ajouté un tableau supplémentaire...
          //FInWhat := fsiwVaisseauChoix;
       end;


    end else if TagName = 'form' then begin
       FInForm := false;

    end;

end;

procedure TParsingFlotte1_ChoixVaisseaux.TraiteContentVaisseauxList(Content: string);
begin

    if FCurrTableLigne < 2 then exit;

    case FCurrTableColonne of
        1: begin
              FCurrentVaisseau.GIDNom := Content;

           end;

        // Tout les autres champs se récupère grâce aux input hidden
    end;


end;

procedure TParsingFlotte1_ChoixVaisseaux.TraiteContentFlotteList(Content: string);
var sTmp: string;
begin

    if FCurrTableLigne < 3 then exit;

    if Content = '' then exit;

    case FCurrTableColonne of
        1: begin
                // Numero
                // <th>1</th>
                FCurrentFlotte.Numero := StrToIntDef(Content, -1);
           end;

        2: begin
                // Mission
                //  <a title="">Transporter</a>
                //  <a title="Aller">(A)</a>

                if (Content[1] = '(') and (length(Content) > 1) then begin
                   Content := lowercase(Content);



                   if Content[2] = LangParsing.GetDataChar('flotte1_cmplw_SensAller', 'a') then begin
                      // .org: 'f'
                      FCurrentFlotte.Direction := odAller;

                      // REMARQUE: la présence du bouton 'Retour' permet de connaitre le sens
                      //           de la flotte
                      // L'analyse de ces caractères est donc inutile...

                      // mais bug avec .org qui utilise la même lettre depuis la version 0.77
                      // on exploite la valeur du title de la balise a si elle a été définit
                      // dans le fichier de langue
                      sTmp := LangParsing.GetData('flotte1_poslw_prediction_retour', '');
                      if sTmp <> '' then begin
                         if pos(lowercase(stmp), lowercase(FLastABaliseTitle)) > 0 then begin
                            // c'est  le sens retour
                            FCurrentFlotte.Direction := odRetour;
                         end;

                      end;

                   end else if Content[2] = LangParsing.GetDataChar('flotte1_cmplw_SensRetour', 'r') then begin
                      // .org: 'r'
                      FCurrentFlotte.Direction := odRetour;

                      sTmp := LangParsing.GetData('flotte1_poslw_prediction_aller', '');
                      if sTmp <> '' then begin
                         if pos(lowercase(stmp), lowercase(FLastABaliseTitle)) > 0 then begin
                            // c'est le sens aller en fait
                            FCurrentFlotte.Direction := odAller;
                         end;

                      end;


                   end else begin
                      // inconnu
                      FError := true;
                   end;


                end else begin
                    // Transporter
                    FCurrentFlotte.Mission := mamOrdreStrToType(Content);

                    // Ressource dans: FLastABaliseTitle
                    FCurrentFlotte.Ressource := mpcExtractRessourceFromBuffer(FLastABaliseTitle);

                end;

           end;

        3: begin
               // Nombre
               // <a title="Petit transporteur: 1">1</a>
               FCurrentFlotte.Nombre    := StrToIntDef(Content, -1);
               FCurrentFlotte.Vaisseaux := FLastABaliseTitle;

           end;

        4: begin
               // Depart
               FCurrentFlotte.Depart := mpcExtractPlanetLocation(Content);

           end;
        5: begin
               // Depart date
               // Thu Nov 24 16:28:36
               FCurrentFlotte.DepartDate := OGDATETIME_StrToUnix(Content);

           end;

        6: begin
               // Arrivee
               FCurrentFlotte.Arrivee := mpcExtractPlanetLocation(Content);

           end;
        7: begin
               // Arrivee date
               // Thu Nov 24 17:31:16
               FCurrentFlotte.ArriveeDate := OGDATETIME_StrToUnix(Content);

               if FCurrentFlotte.ArriveeDate < FCurrentFlotte.DepartDate then begin
                  // l'année doit être différente
                  FCurrentFlotte.ArriveeDate := OGDATETIME_StrToUnix(Content, ThisYear + 1);
               end;

           end;

    end;


end;



procedure TParsingFlotte1_ChoixVaisseaux.ScanOnContent(Sender: TObject; Content: string);
var xPos: integer;
begin


    case FInWhat of
        fsiwNeant: begin
                   // Le passage à la liste des flottes correspond à
                   // <td colspan="8" class="c">Flottes (max. 11)</td>

    {$IFDEF OFFICIER_OK}
                   if FFlotteAmiralDeFlotte then begin
                      if SameText(Content, '+2') then begin
                         FFlotteMax := FFlotteMax + 2;
                         FInWhat := fsiwListDesFlottes;
                         InitFlotte;
                      end;

                      exit;
                   end;
    {$ENDIF}

                   if (FCurrTableLigne <> 1) and (FCurrTableColonne <> 1) then exit;

                   Content := lowercase(trim(Content));



                   if pos(LangParsing.GetData('flotte1_lwpos_Flottes(Max', 'flottes (max'), Content) = 1 then begin
                      // Début de la liste des flottes
                      // "flottes (max. 5)"
                      xPos := LastDelimiter(' ', Content);
                      if xPos = 0 then exit;

                      System.Delete(Content, 1, xPos);

                      // "5)"
                      xPos := pos(')', Content);
                      if xPos = 0 then begin
                         // compte officier probablement
                         // car: Flottes (max. 4 <b><font style="color:lime;">+2</font></b>

                         FFlotteMax := StrToIntDef(Content, -65);

                         if FFlotteMax > 0 then begin
                            FFlotteAmiralDeFlotte := true;
                         end;


                         exit;
                      end;

                      System.Delete(Content, xPos, maxint);

                      // "5" ou "5+2"
                      xPos := pos('+', Content);

                      if xPos > 0 then begin
                         // compte officier
                         // "flottes (max. 5+2)"
                         System.Delete(Content, xPos, maxint);
                         FFlotteMax := StrToIntDef(Content, -65);
                         FFlotteMax := FFlotteMax + 2;

                      end else begin
                         // "flottes (max. 5)"
                         FFlotteMax := StrToIntDef(Content, -1);

                      end;


                      if FFlotteMax < 1 then begin
                         // erreur
                         exit;
                      end;

                      // sinon tout a réussit
                      // change l'état
                      FInWhat := fsiwListDesFlottes;
                      InitFlotte;

                   end;
                end;


        fsiwListDesFlottes: begin
                     TraiteContentFlotteList(trim(Content));

                end;

                
        fsiwVaisseauChoix: begin
                     TraiteContentVaisseauxList(trim(Content));
                end;



    end;


end;




constructor TParsingFlotte1_ChoixVaisseaux.Create;
begin
    inherited;

    FVaisseauxList := TCollectionVaisseauSelInfos.Create;
    FFlotteList    := TCollectionFlotteListEnVoyage.Create;


end;

destructor TParsingFlotte1_ChoixVaisseaux.Destroy;
begin

    FFlotteList.Free;
    FVaisseauxList.Free;

    inherited;
end;


function TParsingFlotte1_ChoixVaisseaux.IsValidVaisseau: boolean;
begin

    if FInWhat <> fsiwVaisseauChoix then begin
       Result := false;
       exit;
    end;

    with FCurrentVaisseau do begin

       if (GID > 0) and (Max >= 0) and (Speed >= 0) and (Consomation >= 0) and (Capacite >= 0) then begin
          // Les sat solaire ont une vitesse/consomation/capacité nulle

          if AllHiddenInput <> '' then begin
             // On ne vérifie pas InputNameForChoix qui peut être vide pour les
             // satellite solaire par exemple

             Result := true;
             exit;

          end;

       end;

    end;

    // sinon
    Result := false;

end;

function TParsingFlotte1_ChoixVaisseaux.IsValidFlotte: boolean;
begin

    if FInWhat <> fsiwListDesFlottes then begin
       Result := false;
       exit;
    end;

    with FCurrentFlotte do begin

       if (Numero > 0) and (Mission <> ooNeant) and (Direction <> odNeant) then begin

          if (Depart.Galaxie > 0) and (DepartDate > 0) and (Arrivee.Galaxie > 0) and (ArriveeDate > 0) then begin
             Result := true;
             exit;
          end;

       end;

    end;

    // sinon
    Result := false;

end;

procedure TParsingFlotte1_ChoixVaisseaux.InitFlotte;
begin
    FCurrentFlotte.Numero    := -1;
    FCurrentFlotte.Mission   := ooNeant;
    FCurrentFlotte.Direction := odNeant;

    FCurrentFlotte.Nombre        := -1;
    FCurrentFlotte.Vaisseaux     := '';
    FCurrentFlotte.Ressource.Metal     := 0;
    FCurrentFlotte.Ressource.Cristal   := 0;
    FCurrentFlotte.Ressource.Deuterium := 0;
    FCurrentFlotte.Ressource.Energie   := 0;

    FCurrentFlotte.Depart.Galaxie   := -1;
    FCurrentFlotte.DepartDate       := 0;
    FCurrentFlotte.Arrivee.Galaxie  := -1;
    FCurrentFlotte.ArriveeDate      := 0;
    
    FCurrentFlotte.ReturnDataToPost := '';
    FCurrentFlotte.ReturnDataURL    := '';

    FFormulaireCountHidden          := 0;
    FFormulaireRetourFound          := false;


end;

procedure TParsingFlotte1_ChoixVaisseaux.InitVaisseau;
begin
    FCurrentVaisseau.GID     := -1;
    FCurrentVaisseau.GIDNom  := '';
    FCurrentVaisseau.Max     := -1;
    FCurrentVaisseau.Speed   := -1;
    FCurrentVaisseau.Consomation := -1;
    FCurrentVaisseau.Capacite    := -1;
    FCurrentVaisseau.AllHiddenInput    := '';
    FCurrentVaisseau.InputNameForChoix := '';
    
    FCurrentVaisseau.QuantiteVoulu := 0;


end;


(*
function ExtractRessourceFromStr(Buffer: string): TOGRessourceAll;
const CHAR_AFTER_NAME = ':';
      CHAR_AFTER_NUMBER = ' ';
var s: string;
    xPos: integer;
begin
    Result.Metal := 0;
    Result.Cristal := 0;
    Result.Deuterium := 0;
    Result.Energie := 0;

    // Buffer := 'Metal: 25.987 Crystal: 20.000 Deuterium: 4.000';
    // MAIS peut également être:
    // Buffer := 'Crystal: 20.000 Deuterium: 4.000';
    // ou encore:
    // Buffer := 'Deuterium: 4.000';

    Result := mpcExtractRessourceFromBuffer(Buffer);
    exit;

    


    xPos := pos(CHAR_AFTER_NAME, Buffer);
    if xPos < 1 then begin
       exit;
    end;

    System.Delete(Buffer, 1, xPos);
    Buffer := trim(Buffer);

    xPos := pos(CHAR_AFTER_NUMBER, Buffer);
    if xPos < 1 then begin
       exit;
    end;

    s := copy(Buffer, 1, xPos - 1);
    s := sfcRemplace(s, '.', '');

    System.Delete(Buffer, 1, xPos);

    if sfcChaineContientQueDesChiffres(s) = false then begin
       // erreur
       exit;
    end;

    Result.Metal := StrToIntDef(s, -1);
    if Result.Metal < 0 then begin
       // erreur
       Result.Metal := 0;
       exit;
    end;


    //
    // Le cristal maintenant
    //


    // Buffer := 'Crystal: 20.000 Deuterium: 4.000';
    xPos := pos(CHAR_AFTER_NAME, Buffer);
    if xPos < 1 then begin
       exit;
    end;

    System.Delete(Buffer, 1, xPos);
    Buffer := trim(Buffer);

    xPos := pos(CHAR_AFTER_NUMBER, Buffer);
    if xPos < 1 then begin
       exit;
    end;

    s := copy(Buffer, 1, xPos - 1);
    s := sfcRemplace(s, '.', '');

    System.Delete(Buffer, 1, xPos);

    if sfcChaineContientQueDesChiffres(s) = false then begin
       // erreur
       exit;
    end;

    Result.Cristal := StrToIntDef(s, -1);
    if Result.Cristal < 0 then begin
       // erreur
       Result.Cristal := 0;
       exit;
    end;



    //
    // Le deutérium
    //

    // Buffer := 'Deuterium: 4.000';

    xPos := pos(CHAR_AFTER_NAME, Buffer);
    if xPos < 1 then begin
       exit;
    end;

    System.Delete(Buffer, 1, xPos);
    Buffer := trim(Buffer);

    // Buffer := '4.000';


    xPos := pos(CHAR_AFTER_NUMBER, Buffer);
    if xPos < 1 then begin
       // c'est normal si il n'est pas trouvé
       s := Buffer;
    end else begin
       s := copy(Buffer, 1, xPos - 1);
    end;

    s := sfcRemplace(s, '.', '');

    if sfcChaineContientQueDesChiffres(s) = false then begin
       // erreur
       exit;
    end;


    Result.Deuterium := StrToIntDef(s, -1);
    if Result.Deuterium < 0 then begin
       // erreur
       Result.Deuterium := 0;
       exit;
    end;

end;
*)

end.
